package com.ganzalang.gmall.command.inventory.updater;

import com.ganzalang.gmall.command.domain.ProductVariantInventory;
import com.ganzalang.gmall.command.domain.ProductVariantInventoryLog;
import com.ganzalang.gmall.command.event.InventoryChangeEvent;
import com.ganzalang.gmall.command.service.ProductVariantInventoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @description: 商品库存更新命令的基类
 * @author: ganziliang
 * @Date 2021/3/13 10:02
 */
@Slf4j
public abstract class AbstractInventoryUpdater implements InventoryUpdater{

    /**
     * 商品库存service组件
     */
    protected ProductVariantInventoryService inventoryService;

    /**
     * 商品库存DO对象
     */
    protected List<ProductVariantInventory> productVariantInventories;

    /**
     * 商品库存日志DO对象
     */
    protected List<ProductVariantInventoryLog> productVariantInventoryLogs;

    /**
     * 事件发布组件
     */
    protected ApplicationEventPublisher publisher;

    /**
     * 店铺ID
     */
    protected Long shopId;

    /**
     * 构造方法
     * @param inventoryService 商品库存service组件
     * @param productVariantInventories 商品库存DO对象
     * @param publisher 事件发布组件
     */
    public AbstractInventoryUpdater(
            ProductVariantInventoryService inventoryService,
            List<ProductVariantInventory> productVariantInventories,
            ApplicationEventPublisher publisher,
            Long shopId) {
        this.inventoryService = inventoryService;
        this.productVariantInventories = productVariantInventories;
        this.publisher = publisher;
        this.shopId = shopId;
    }

    /**
     * 更新sku的库存
     * @return 处理结果
     */
    @Override
    public Boolean updateSkusInventory() {
        try{
            updateAvailableInventory();
            updateLockInventory();
            updateInventoryLog();
            executeUpdateSkusInventory();
        }catch (Exception e){
            log.error("扣减库存出错",e);
            rollback();
            return false;
        }
        return true;
    }

    /**
     * 更新可用库存
     */
    protected abstract void updateAvailableInventory();

    /**
     * 更新锁定库存
     */
    protected abstract void updateLockInventory();

    /**
     * 更新库存日志表
     */
    protected abstract void updateInventoryLog();

    /**
     * 回滚操作
     */
    protected abstract void rollback();
    /**
     * 实际执行sku库存更改入库的操作
     */
    private void executeUpdateSkusInventory(){
        if(!CollectionUtils.isEmpty(productVariantInventories)){
            //更新数据库库存
            inventoryService.updateInventoryToDB(shopId, productVariantInventories);
        }
        if(!CollectionUtils.isEmpty(productVariantInventoryLogs)) {
            //发布异步事件,写入库存变更日志
            InventoryChangeEvent inventoryChangeEvent = new InventoryChangeEvent();
            inventoryChangeEvent.setProductVariantInventoryLogs(productVariantInventoryLogs);
            publisher.publishEvent(inventoryChangeEvent);
        }
    }
}
